package utils

import (
	"commerce/common"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"hash"
	"io"
	"net/http"
	"time"
)

// callbackUrl为 上传回调服务器的URL，请将下面的IP和Port配置为您自己的真实信息。
//var callbackUrl string = "http://88.88.88.88:8888";
// 用户上传文件时指定的前缀。
//var upload_dir = "/"
var expire_time int64 = 30

func get_gmt_iso8601(expire_end int64) string {
	var tokenExpire = time.Unix(expire_end, 0).UTC().Format("2006-01-02T15:04:05Z")
	return tokenExpire
}

type ConfigStruct struct {
	Expiration string     `json:"expiration"`
	Conditions [][]string `json:"conditions"`
}

type PolicyToken struct {
	AccessKeyId string `json:"accessid"`
	Host        string `json:"host"`
	Expire      int64  `json:"expire"`
	Signature   string `json:"signature"`
	Policy      string `json:"policy"`
	Directory   string `json:"dir"`
	Callback    string `json:"callback"`
}

type CallbackParam struct {
	CallbackUrl      string `json:"callbackUrl"`
	CallbackBody     string `json:"callbackBody"`
	CallbackBodyType string `json:"callbackBodyType"`
}

func GetPolicyToken() string {

	upload_dir := time.Now().Format("2006-01-02") + "/"

	oc := common.AppConfig.OssConfig
	now := time.Now().Unix()
	expire_end := now + expire_time
	var tokenExpire = get_gmt_iso8601(expire_end)

	//create post policy json
	var config ConfigStruct
	config.Expiration = tokenExpire
	var condition []string
	condition = append(condition, "starts-with")
	condition = append(condition, "$key")
	condition = append(condition, upload_dir)
	config.Conditions = append(config.Conditions, condition)

	//calucate signature
	result, err := json.Marshal(config)
	debyte := base64.StdEncoding.EncodeToString(result)
	h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(oc.AccessKeySecret))
	io.WriteString(h, debyte)
	signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))

	//var callbackParam CallbackParam
	//callbackParam.CallbackUrl = callbackUrl
	//callbackParam.CallbackBody = "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}"
	//callbackParam.CallbackBodyType = "application/x-www-form-urlencoded"
	//callback_str,err:=json.Marshal(callbackParam)
	//if err != nil {
	//	fmt.Println("callback json err:", err)
	//}
	//callbackBase64 := base64.StdEncoding.EncodeToString(callback_str)

	var policyToken PolicyToken
	policyToken.AccessKeyId = oc.AccessKeyId
	policyToken.Host = fmt.Sprintf("https://%s.%s", oc.BucketName, oc.Endpoint)
	policyToken.Expire = expire_end
	policyToken.Signature = signedStr
	policyToken.Directory = upload_dir
	policyToken.Policy = debyte
	//policyToken.Callback = string(callbackBase64)
	response, err := json.Marshal(policyToken)
	if err != nil {
		common.Error.Println("json err:", err)
	}
	return string(response)
}

func handlerRequest(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		response := GetPolicyToken()
		w.Header().Set("Access-Control-Allow-Methods", "POST")
		w.Header().Set("Access-Control-Allow-Origin", "*")
		io.WriteString(w, response)
	}
}

func Upload(fd io.Reader, fileName string) (string, error) {
	var oc = common.AppConfig.OssConfig
	// 创建OSSClient实例。
	client, err := oss.New(oc.Endpoint, oc.AccessKeyId, oc.AccessKeySecret)
	//client, err := oss.New(e, ak, as)
	if err != nil {
		return "", err
	}
	// 获取存储空间。
	bucket, err := client.Bucket(oc.BucketName)
	//bucket, err := client.Bucket(b)
	if err != nil {
		return "", err
	}
	fileName = FilenamePrefix() + "_" + fileName
	// 上传文件流。
	return fmt.Sprintf("https://%s.%s/%s", oc.BucketName, oc.Endpoint, fileName),
		//return fmt.Sprintf("https://%s.%s/%s", b, e, fileName),
		bucket.PutObject(fileName, fd)
}

func Delete(filepath string) error {

	var oc = common.AppConfig.OssConfig
	// 创建OSSClient实例。
	client, err := oss.New(oc.Endpoint, oc.AccessKeyId, oc.AccessKeySecret)
	//client, err := oss.New(e, ak, as)
	if err != nil {
		return err
	}
	// 获取存储空间。
	bucket, err := client.Bucket(oc.BucketName)
	//bucket, err := client.Bucket(b)
	if err != nil {
		return err
	}
	return bucket.DeleteObject(filepath)
}

func BatchDelete(filepath []string) error {

	var oc = common.AppConfig.OssConfig
	// 创建OSSClient实例。
	client, err := oss.New(oc.Endpoint, oc.AccessKeyId, oc.AccessKeySecret)
	if err != nil {
		return err
	}
	// 获取存储空间。
	bucket, err := client.Bucket(oc.BucketName)
	if err != nil {
		return err
	}
	_, err = bucket.DeleteObjects(filepath, oss.DeleteObjectsQuiet(true))
	return err
}
